

from sketchc import *
# ~ from numpy import linspace


window = Window3((1000, 800))



chair = Obj()
b1 = make_block(U3(0.4, 0.4, 0.05))     # 坐垫
b1.t.pos = U3(0, 0, -0.8)
b1.as_unit() >> chair
b = make_block(U3(0.05, 0.05, 0.4))     #椅子腿
b.pile(b1.box.anchor(U3.c5), anchor=U3.c1)
b.as_unit() >> chair
b.pile(b1.box.anchor(U3.c6), anchor=U3.c2)
b.as_unit() >> chair
b.pile(b1.box.anchor(U3.c7), anchor=U3.c3)
b.as_unit() >> chair
b.pile(b1.box.anchor(U3.c8), anchor=U3.c4)
b.as_unit() >> chair
b = make_block(U3(0.05, 0.05, 0.2)) # 椅背支撑
b.pile(b1.box.anchor(U3.c3), anchor=U3.c7)
b.as_unit() >> chair
b.pile(b1.box.anchor(U3.c4), anchor=U3.c8)
b.as_unit() >> chair
bl = b
b = make_block(U3(0.4, 0.05, 0.2))  # 椅背
b.pile(bl.box.anchor(U3.c4), anchor=U3.c8)
b.as_unit() >> chair

chair.box = Box(U3(1, 1, 1), chair)
chair.prog = prog2
chair.color = V3(1.0, 1.0, 1.0)
chair.u(window.ctx)

t_block = chair


sc = Obj()
sc.color = V3(1.0, 1.0, 1.0)
sc.prog = prog2
t1 = Turtle()
t2 = Turtle(U3(0, 3, 0), vrot(U3.up, pi))
t2.connect(t1)
for i in range(30):
    d  = i + 3
    k = int(tau * d  / 1)
    t2.set(pos=U3(0, d, 0), rot=vrot(U3.up, pi))
    for i in range(k):
        t1.walk(rot=vrot(U3.up, tau / k))
        t2.pile(t_block, anchor=U3.bk+U3.dn)
        t_block.as_unit() >> sc

sc.u(window.ctx)
sc >> window


camera = Camera(U3(0, -10, 1))
camera >> window

walker = Walker(camera)
walker >> window

# ~ cube = make_block(U3(0.5, 0.5, 0.5))
# ~ cube.color = V3(1, 1, 1)
# ~ cube.prog = prog2
# ~ cube.u(window.ctx)
# ~ cube >> window


# ~ @id(lambda f:window.update_callback.append(f) or f)
# ~ def f(window, dt):
    # ~ cube.t.walk(rot=vrot(U3.c2, dt  * 2))

# ~ block5 = make_block(U3(1,1,1))
# ~ block5.t.pos = U3(0, 2, 0)
# ~ block5.u(window.ctx)
# ~ block5 >> window

# ~ block6 = make_block(U3(1,1,1))
# ~ block6.t.pos = U3(0.5, 2.1, 0.5)
# ~ block6.u(window.ctx)
# ~ block6 >> window

#######################



class Flower(Drawable, Moveable):
    def __init__(self, k, obj, t=None):
        self.angle1 = 0
        self.angle2 = 0
        self.arm = 1
        if t is None:
            self.t = Turtle()
        else:
            assert isinstance(t, Turtle)
            self.t = t
        @mapf(range(k))
        def group1(i):
            return Turtle(rot=vrot(U3.up, tau / k * i), parent=self.t)
        self.group1= group1
        @mapf(group1)
        def group2(t):
            return Turtle(rot=vrot(U3.rt, self.angle1), parent=t)
        self.group2= group2
        @mapf(group2)
        def group3(t):
            return Turtle(pos=U3(0, self.arm, 0), rot=vrot(U3.up, pi), parent=t)
        self.group3= group3
        @mapf(group3)
        def group4(t):
            return Turtle(rot=vrot(U3.rt, self.angle2), parent=t)
        self.group4= group4
        @mapf(group4)
        def group_obj(t):
            o_new = obj.copy()
            o_new.t = t
            return o_new
        self.group_obj = group_obj

    def draw(self, camera):
        for obj in self.group_obj:
            obj.draw(camera)

    def draw_normal(self, camera):
        for obj in self.group_obj:
            obj.draw_normal(camera)

    def update(self):
        for t in self.group2:
            t.set(rot=vrot(U3.rt, self.angle1))
        for t in self.group3:
            t.set(pos=U3(0, self.arm, 0))
        for t in self.group4:
            t.set(rot=vrot(U3.rt, self.angle2))


plate = make_circle("xy", 0.8, 15)
plate.color = V3(1, 1, 1)
plate.prog = prog2
plate.u(window.ctx)
plate.t.set(pos=U3(0, 0, -0.3))
plate >> window




piece = make_tri(U3(0.3, 0, 0), U3(-0.3, 0, 0), U3(0, 0, 1))
piece.color = V3(1, 1, 1)
piece.prog = prog2
piece.u(window.ctx)

f1 = Flower(5, piece)
f1 >> window


f2 = Flower(5, piece, t=Turtle(rot=vrot(U3.up, tau/5 / 3)))
f2 >> window

f3 = Flower(5, piece, t=Turtle(rot=vrot(U3.up, tau/ 5 /3 * 2)))
f3 >> window


if "controls":

    uo = V2(-4.5, -3)

    ti = lambda k: (k / 1.5 + 1) / 2
    ti2 = lambda k: k / 2

    @join(window)
    @pair
    class pa1:
        p = uo + grid(0, 0)
        k = ti(-0.7)
        color = (255, 0, 0)
        t = lambda k: (k * 2 - 1) * 1.5
        def f(k):
            f1.angle1 = k
            f1.update()


    @join(window)
    @pair
    class pa2:
        p = uo + grid(0, 1)
        k = ti2(0.8)
        color = (255, 0, 0)
        t = lambda k: (k * 2)
        def f(k):
            f1.arm = k
            f1.update()


    @join(window)
    @pair
    class pa3:
        p = uo + grid(0, 2)
        k = 0.5
        color = (255, 0, 0)
        t = lambda k: (k * 2 - 1) * 1.5
        def f(k):
            f1.angle2 = k
            f1.update()



    @join(window)
    @pair
    class pa4:
        p = uo + grid(1, 0)
        k = ti(-0.8)
        color = (255, 0, 0)
        t = lambda k: (k * 2 - 1) * 1.5
        def f(k):
            f2.angle1 = k
            f2.update()


    @join(window)
    @pair
    class pa5:
        p = uo + grid(1, 1)
        k = ti2(0.9)
        color = (255, 0, 0)
        t = lambda k: (k * 2)
        def f(k):
            f2.arm = k
            f2.update()


    @join(window)
    @pair
    class pa6:
        p = uo + grid(1, 2)
        k = 0.5
        color = (255, 0, 0)
        t = lambda k: (k * 2 - 1) * 1.5
        def f(k):
            f2.angle2 = k
            f2.update()



    @join(window)
    @pair
    class pa7:
        p = uo + grid(2, 0)
        k = ti(-0.9)
        color = (255, 0, 0)
        t = lambda k: (k * 2 - 1) * 1.5
        def f(k):
            f3.angle1 = k
            f3.update()


    @join(window)
    @pair
    class pa8:
        p = uo + grid(2, 1)
        k = ti2(1)
        color = (255, 0, 0)
        t = lambda k: (k * 2)
        def f(k):
            f3.arm = k
            f3.update()


    @join(window)
    @pair
    class pa9:
        p = uo + grid(2, 2)
        k = 0.5
        color = (255, 0, 0)
        t = lambda k: (k * 2 - 1) * 1.5
        def f(k):
            f3.angle2 = k
            f3.update()







clock = pygame.time.Clock()
while True:
    dt = clock.tick(60)
    window.update(dt)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            exit()
        window.dispatch(e)
    window.render()   # screen 操作需要写在window的槽里
    pygame.display.flip()

